/**
 * Copyright (C) 2009 Gero Vermaas <gero@vermaas.net>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.vermaas.blogger;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import org.apache.log4j.Logger;

/**
 * Utility tool to run before yo do the actual import of the blog entries.
 * This tool validates the http(s) links in your blog entries and reports to the log
 * file if the links are still valid or can be changed as part of the
 * import process into a valid link. You can use this information to do
 * some clean up before doing the actual import or after importing the
 * blog entries.
 *
 * By default the tool will read it settings from the {@link DEFAULT_SETTINGS_FILE}
 * file, but you can pass in another settings file as argument.
 *
 * @author Gero Vermaas
 */
public class BlogLinkValidatorTool {

  private static final String BLOGSOURCECLASS = "blogSourceClass";
  private static final String CHANGERELATIVEHREFS = "changeRelativeHrefs";
  private static final String CURRENTBLOGPATH = "currentBlogPath";
  private static final String RELATIVEHREFSPREFIX = "relativeHrefsPrefix";

  private Properties settings = new Properties();
  private final static String DEFAULT_SETTINGS_FILE = "bloggerimporter.properties";

  private static final Logger log = Logger.getLogger(BlogLinkValidatorTool.class);

  /**
   *
   * @param args args[0] is the (optional) path to the file containing the
   *             settings to be used. If not specified it will use
   *             {@link DEFAULT_SETTINGS_FILE}.
   */
  public static void main(String[] args) {

    BlogLinkValidatorTool bi = new BlogLinkValidatorTool();
    String settingsFile = DEFAULT_SETTINGS_FILE;
    if (args.length > 0) {
      settingsFile = args[0];
    }
    bi.validateLinks(settingsFile);
  }

  /*
   * Validates all http(s) links found in the blog entries.
   * @param settingsFile Path to file containing settings.
   */
  void validateLinks(String settingsFile) {
    log.debug("validateLinks");
    try {
      settings.load(new FileInputStream(settingsFile));

      BlogSource blogSource = getBlogSource();
      blogSource.setSettings(settings);

      LinkValidator lv = new LinkValidator(
        Boolean.parseBoolean(settings.getProperty(CHANGERELATIVEHREFS)),
        settings.getProperty(RELATIVEHREFSPREFIX),
        settings.getProperty(CURRENTBLOGPATH));

      while (blogSource.hasNext()) {
        BlogPostDetails bpd = (BlogPostDetails) blogSource.next();

        List<String> failedLinks = lv.validateAndFixLinks(bpd, new HashMap<String, String>());
        if (failedLinks.size() > 0) {
          log.info("The following post has failing links: " + bpd.getOriginalPostId());
          log.info("The failing links are");
          for (String link: failedLinks) {
            log.info(link);
          }
          log.info("================================================");
          
        }
      }

    } catch (IOException ioe) {
      throw new RuntimeException(ioe);
    }
  }

  /**
   * Instantiaties the BlogSource to use using the {@link BLOGSOURCECLASS}
   * setting.
   * @return Instantiated BlogSource.
   */
  BlogSource getBlogSource() {
    Class blogSourceClass;
    try {
      blogSourceClass = Class.forName(settings.getProperty(BLOGSOURCECLASS));
      return (BlogSource)blogSourceClass.newInstance();
    } catch (Exception ex) {
      log.error("Could not instantiate blogSource: " + settings.getProperty(BLOGSOURCECLASS));
      throw new RuntimeException(ex);
    }
  }
}
